package com.smcaiot.filesync.starter.task;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.smcaiot.filesync.starter.app.FileSyncProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.sql.SQLException;
import java.util.Objects;

import static com.smcaiot.filesync.starter.constants.Constants.YES;

/**
 * @Author: cz
 * @Date: 2023/6/28
 * @Description:
 */
@Component
@EnableScheduling
@Slf4j
public class FileSyncTask implements SchedulingConfigurer {

    @Autowired
    private FileSyncProperties fileSyncProp;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        fileSyncProp.getSchedules().stream().filter(schedule -> schedule.getOpen())
                .forEach(schedule -> addTask(schedule, taskRegistrar));
    }

    private Entity findScheduleInfoById(Integer id) {
        try {
            if (Objects.isNull(id)) {
                return new Entity();
            }
            return Db.use().queryOne("select * from schedule_info where id = ?", id);
        } catch (Exception e) {
            log.warn("查询数据库定时任务配置失败：{}", e.getMessage());
            return new Entity();
        }
    }

    private void addTask(FileSyncProperties.Schedule schedule, ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(
                () -> runTask(schedule),
                triggerContext -> {
                    Entity entity = findScheduleInfoById(schedule.getId());
                    if (Objects.nonNull(schedule.getId())) {
                        fileSyncProp.updateSchedule(schedule, entity);
                    }
                    if (StrUtil.isBlank(schedule.getCron())) {
                        log.warn("任务`{}`的cron不能为空，请配置！", schedule.getName());
                        return null;
                    }
                    if(!YES.equals(entity.getStr("schedule_open"))){
                        log.warn("任务`{}`的开关是关闭的！", schedule.getName());
                        return null;
                    }
                    return new CronTrigger(schedule.getCron()).nextExecutionTime(triggerContext);
                });
    }

    private void runTask(FileSyncProperties.Schedule schedule) {
        try {
            long begin = System.currentTimeMillis();
            log.debug("开始{}.., cron: {}", schedule.getName(), schedule.getCron());
            schedule.getRunnable().run();
            long end = System.currentTimeMillis();
            log.debug("结束{}..耗时：{} 秒", schedule.getName(), ((end - begin) / 1000));
        } catch (Exception e) {
            log.warn("{}失败：{}", schedule.getName(), e);
        }
    }

}
